package com.am.server.api.system.user.dao.rdb.impl;

import com.am.server.api.system.user.dao.rdb.AdminUserDao;
import com.am.server.api.system.user.model.dto.AdminUserListQueryDto;
import com.am.server.api.system.user.model.entity.AdminUserEntity;
import com.am.server.api.system.user.model.entity.QAdminUserEntity;
import com.am.server.api.system.user.repository.AdminUserRepository;
import com.querydsl.core.BooleanBuilder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author 阮雪峰
 */
@Service
public class AdminUserDaoImpl implements AdminUserDao {

    private final AdminUserRepository adminUserRepository;

    public AdminUserDaoImpl(AdminUserRepository adminUserRepository) {
        this.adminUserRepository = adminUserRepository;
    }

    @Override
    public Optional<AdminUserEntity> findByEmail(String email) {
        return adminUserRepository.findByEmail(email);
    }

    @Override
    public Optional<AdminUserEntity> findByIdNotAndEmail(Long id, String email) {
        return adminUserRepository.findByIdNotAndEmail(id, email);
    }

    @Override
    public Optional<AdminUserEntity> findByUsername(String username) {
        return adminUserRepository.findByUsername(username);
    }

    @Override
    public Optional<AdminUserEntity> findByIdNotAndUsername(Long id, String username) {
        return adminUserRepository.findByIdNotAndUsername(id, username);
    }

    @Override
    public Optional<AdminUserEntity> findById(Long id) {
        return adminUserRepository.findById(id);
    }

    @Override
    public Page<AdminUserEntity> findAll(AdminUserListQueryDto query) {
        QAdminUserEntity entity = QAdminUserEntity.adminUserEntity;
        Optional<AdminUserListQueryDto> optional = Optional.of(query);

        BooleanBuilder booleanBuilder = new BooleanBuilder(entity.id.isNotNull());
        optional.map(AdminUserListQueryDto::getUsername).ifPresent(username -> booleanBuilder.and(entity.username.containsIgnoreCase(username)));
        optional.map(AdminUserListQueryDto::getName).ifPresent(name -> booleanBuilder.and(entity.username.contains(name)));
        optional.map(AdminUserListQueryDto::getEmail).ifPresent(email -> booleanBuilder.and(entity.email.containsIgnoreCase(email)));

        return adminUserRepository.findAll(Objects.requireNonNull(booleanBuilder.getValue()), PageRequest.of(query.getPage() - 1, query.getPageSize(), Sort.by(Sort.Direction.DESC, entity.id.getMetadata().getName())));
    }

    @Override
    public void save(AdminUserEntity user) {
        adminUserRepository.save(user);
    }

    @Override
    public void deleteById(Long id) {
        adminUserRepository.deleteById(id);
    }

    @Override
    public List<AdminUserEntity> findAllById(List<Long> ids) {
        return adminUserRepository.findAllById(ids);
    }

    @Override
    public void saveAll(List<AdminUserEntity> users) {
        adminUserRepository.saveAll(users);
    }
}
